package backpropagation;

import java.util.ArrayList;
import java.util.Random;

public class SigmoidUnit {

	private ArrayList<Double> pesos;
	private ArrayList<Double> ultimaEntrada;
	public static double tazaAprendizaje = 1;

	SigmoidUnit(int cantEntradas, Random generator) {
		pesos = new ArrayList();
		for (int i = 0; i < cantEntradas + 1; i++) {
			double peso = (generator.nextDouble() - 0.5) * 0.1;
			pesos.add(peso);
		}				
		ultimaEntrada = null;
	}

	ArrayList<Double> getPesos(){
		return pesos;
	}

	double computar(ArrayList<Double> x) {
		ultimaEntrada = new ArrayList(x);
		double ret = 0;
		int i = 0;
		while (i < x.size()) {
			ret += pesos.get(i) * x.get(i);
			i++;
		}
		ret += pesos.get(i);
		ret = 1.0 / (1.0 + Math.exp(-ret));

		return ret;
	}

	double aprenderOutput(double targetOut) {
		if(ultimaEntrada == null){
			System.out.println("ERROR: ultimaEntrada == null");
		}		
		double error = 0;
		double nodoOut = this.computar(ultimaEntrada);
		error = nodoOut * (1 - nodoOut) * (targetOut - nodoOut);
		int i = 0;
		while (i < ultimaEntrada.size()) {
			double delta = tazaAprendizaje * error * ultimaEntrada.get(i);
			pesos.set(i, pesos.get(i) + delta);
			i++;
		}
		double delta = tazaAprendizaje * error * 1;
		pesos.set(i, pesos.get(i) + delta);
		return error;
	}

	double aprenderHidden(double errorSiguienteLayer, double pesoSiguienteLayer) {
		if(ultimaEntrada == null){
			System.out.println("ERROR: ultimaEntrada == null");
		}
//		System.out.println("Ultima Entrada: \n"+ultimaEntrada);
		double error = 0;
		double nodoOut = this.computar(ultimaEntrada);
		error = nodoOut * (1 - nodoOut) * pesoSiguienteLayer* errorSiguienteLayer;
		int i = 0;
		while (i < ultimaEntrada.size()) {
			double delta = tazaAprendizaje * error * ultimaEntrada.get(i);
			pesos.set(i, pesos.get(i) + delta);
			i++;
		}
		double delta = tazaAprendizaje * error * 1;
		pesos.set(i, pesos.get(i) + delta);
		return error;
	}
}
